﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

// namespace VR_ChuangKe.Share
// {
    public class LayoutManualRefrash : MonoSingleton<LayoutManualRefrash>
    {
        private List<Transform> _waitHideList;
        private List<Transform> _waitActiveList;
        private List<Transform> _activeinEndList;
        private List<Transform> _notUpdateParentList;
        private Dictionary<Transform, int> _waitActiveDict;
        public override void OnInit()
        {
            _waitHideList = new List<Transform>();
            _waitActiveList = new List<Transform>();
            _activeinEndList = new List<Transform>();
            _notUpdateParentList = new List<Transform>();
            _waitActiveDict = new Dictionary<Transform, int>();
        }

        private void LateUpdate()
        {
            OnUpdate();
        }

        public override void OnUpdate()
        {
            if (_waitHideList.Count > 0)
            {
                Transform[] ts = _waitHideList.ToArray();
                for (int i = 0; i < ts.Length; i++)
                {
                    Transform rt = ts[i];
                    if (rt == null)
                    {
                        _waitHideList.Remove(rt);
                        _waitActiveDict.Remove(rt);
                        _activeinEndList.Remove(rt);
                        _notUpdateParentList.Remove(rt);
                    }
                    else if (rt.gameObject.activeInHierarchy)
                    {
                        _waitHideList.Remove(rt);
                        if (rt.gameObject.GetComponent<RectTransform>() != null) LayoutRebuilder.ForceRebuildLayoutImmediate(rt.gameObject.GetComponent<RectTransform>());
                        if (_notUpdateParentList.Contains(rt))
                        {
                            ActiveLayout(rt, _activeinEndList.Contains(rt));
                            _notUpdateParentList.Remove(rt);
                        }
                        else if (rt.name != "Content")
                        {
                            ActiveLayout(rt, _activeinEndList.Contains(rt));
                            if (rt.parent != null)
                                SetDirty(rt.parent);
                        }
                        _activeinEndList.Remove(rt);

                    }
                }
            }
            if (_waitActiveList.Count > 0)
            {
                Transform[] ts = _waitActiveList.ToArray();
                for (int i = 0; i < ts.Length; i++)
                {
                    Transform rt = ts[i];
                    if (rt == null)
                    {
                        _waitActiveList.Remove(rt);
                        _waitActiveDict.Remove(rt);
                    }
                    if (rt != null && rt.gameObject.activeInHierarchy)
                    {
                        EnableLayout(rt);
                        if (!_waitActiveDict.ContainsKey(rt) || _waitActiveDict[rt] <= 0)
                        {
                            if(rt.gameObject.GetComponent<RectTransform>() != null) LayoutRebuilder.ForceRebuildLayoutImmediate(rt.gameObject.GetComponent<RectTransform>());
                            _waitHideList.Add(rt);
                            _waitActiveList.Remove(rt);
                            _waitActiveDict.Remove(rt);
                        }
                    }
                }

            }
            if (_waitActiveList.Count == 0 && _waitHideList.Count == 0)
            {
                enabled = false;
            }
        }

        private void SetDirty(Transform rt)
        {
            if (rt == null || !rt.gameObject.activeSelf || (rt.name == "Content" && !ContainLayout(rt.parent)))
                return;
            if (rt.name == "Content_Order" && rt.Find("Empty") != null)
            {
                rt.Find("Empty").gameObject.SetActive(rt.childCount == 1);
            }
            if (rt.name == "Content_Number" && rt.Find("Number") != null)
            {
                rt.Find("Number").gameObject.SetActive(rt.childCount == 1);
            }
            enabled = true;
            ActiveLayout(rt, false);
            if (!_waitActiveList.Contains(rt))
            {

                _waitActiveList.Add(rt);
                if (_waitHideList.Contains(rt))
                    _waitHideList.Remove(rt);
                _waitActiveDict[rt] = 0;
                LayoutElement le = rt.GetComponent<LayoutElement>();
                AspectRatioFitter arf = rt.GetComponent<AspectRatioFitter>();
                ContentSizeFitter csf = rt.GetComponent<ContentSizeFitter>();
                GridLayoutGroup glg = rt.GetComponent<GridLayoutGroup>();
                VerticalLayoutGroup vlg = rt.GetComponent<VerticalLayoutGroup>();
                HorizontalLayoutGroup hlg = rt.GetComponent<HorizontalLayoutGroup>();

                if (le != null)
                {
                    _waitActiveDict[rt]++;
                }
                if (arf != null)
                {
                    _waitActiveDict[rt]++;
                }
                if (csf != null)
                {
                    _waitActiveDict[rt]++;
                }
                if (glg != null)
                {
                    _waitActiveDict[rt]++;
                }
                if (vlg != null)
                {
                    _waitActiveDict[rt]++;
                }
                if (hlg != null)
                {
                    _waitActiveDict[rt]++;
                }
            }

        }

        private bool ContainLayout(Transform rt)
        {
            LayoutElement le = rt.GetComponent<LayoutElement>();
            AspectRatioFitter arf = rt.GetComponent<AspectRatioFitter>();
            ContentSizeFitter csf = rt.GetComponent<ContentSizeFitter>();
            GridLayoutGroup glg = rt.GetComponent<GridLayoutGroup>();
            VerticalLayoutGroup vlg = rt.GetComponent<VerticalLayoutGroup>();
            HorizontalLayoutGroup hlg = rt.GetComponent<HorizontalLayoutGroup>();

            if (le != null || arf != null || csf != null || glg != null || vlg != null || hlg != null)
            {
                return true;
            }
            return false;
        }

        private void EnableLayout(Transform rt)
        {
            if (rt == null || !_waitActiveDict.ContainsKey(rt))
                return;
            LayoutElement le = rt.GetComponent<LayoutElement>();
            AspectRatioFitter arf = rt.GetComponent<AspectRatioFitter>();
            ContentSizeFitter csf = rt.GetComponent<ContentSizeFitter>();
            GridLayoutGroup glg = rt.GetComponent<GridLayoutGroup>();
            VerticalLayoutGroup vlg = rt.GetComponent<VerticalLayoutGroup>();
            HorizontalLayoutGroup hlg = rt.GetComponent<HorizontalLayoutGroup>();
            bool isEnable = true;
            if (le != null && !le.enabled)
            {
                le.enabled = isEnable;
                _waitActiveDict[rt]--;
                return;
            }
            if (glg != null && !glg.enabled)
            {
                glg.enabled = isEnable;
                _waitActiveDict[rt]--;
                return;
            }
            if (vlg != null && !vlg.enabled)
            {
                vlg.enabled = isEnable;
                _waitActiveDict[rt]--;
                return;
            }
            if (hlg != null && !hlg.enabled)
            {
                hlg.enabled = isEnable;
                _waitActiveDict[rt]--;
                return;
            }
            if (arf != null && !arf.enabled)
            {
                arf.enabled = isEnable;
                _waitActiveDict[rt]--;
                return;
            }
            if (csf != null && !csf.enabled)
            {
                csf.enabled = isEnable;
                _waitActiveDict[rt]--;
                return;
            }
            _waitActiveDict[rt] = 0;
        }

        private void ActiveLayout(Transform rt, bool isEnable)
        {

            LayoutElement le = rt.GetComponent<LayoutElement>();
            AspectRatioFitter arf = rt.GetComponent<AspectRatioFitter>();
            ContentSizeFitter csf = rt.GetComponent<ContentSizeFitter>();
            GridLayoutGroup glg = rt.GetComponent<GridLayoutGroup>();
            VerticalLayoutGroup vlg = rt.GetComponent<VerticalLayoutGroup>();
            HorizontalLayoutGroup hlg = rt.GetComponent<HorizontalLayoutGroup>();

            if (le != null)
            {
                le.enabled = isEnable;
            }
            if (glg != null)
            {
                glg.enabled = isEnable;
            }
            if (vlg != null)
            {
                vlg.enabled = isEnable;
            }
            if (hlg != null)
            {
                hlg.enabled = isEnable;
            }
            if (arf != null)
                arf.enabled = isEnable;
            if (csf != null)
            {
                csf.enabled = isEnable;

            }
        }

        public static void ForceUpdateLayout(Transform rt, bool updateParent = false, bool aciveInEnd = true)
        {
            if (rt == null || !LayoutManualRefrash.Instance.ContainLayout(rt))
                return;
            LayoutManualRefrash.Instance.enabled = true;
            LayoutManualRefrash.Instance.ActiveLayout(rt, false);
            if (!LayoutManualRefrash.Instance._waitActiveList.Contains(rt))
            {
                LayoutManualRefrash.Instance._waitActiveList.Add(rt);
                if (LayoutManualRefrash.Instance._waitHideList.Contains(rt))
                    LayoutManualRefrash.Instance._waitHideList.Remove(rt);

                LayoutManualRefrash.Instance._waitActiveDict[rt] = 0;
                LayoutElement le = rt.GetComponent<LayoutElement>();
                AspectRatioFitter arf = rt.GetComponent<AspectRatioFitter>();
                ContentSizeFitter csf = rt.GetComponent<ContentSizeFitter>();
                GridLayoutGroup glg = rt.GetComponent<GridLayoutGroup>();
                VerticalLayoutGroup vlg = rt.GetComponent<VerticalLayoutGroup>();
                HorizontalLayoutGroup hlg = rt.GetComponent<HorizontalLayoutGroup>();

                if (le != null)
                {
                    LayoutManualRefrash.Instance._waitActiveDict[rt]++;
                }
                else if (arf != null)
                {
                    LayoutManualRefrash.Instance._waitActiveDict[rt]++;
                }
                else if (csf != null)
                {
                    LayoutManualRefrash.Instance._waitActiveDict[rt]++;
                }
                else if (glg != null)
                {
                    LayoutManualRefrash.Instance._waitActiveDict[rt]++;
                }
                else if (vlg != null)
                {
                    LayoutManualRefrash.Instance._waitActiveDict[rt]++;
                }
                else if (hlg != null)
                {
                    LayoutManualRefrash.Instance._waitActiveDict[rt]++;
                }
            }
            if (aciveInEnd && !LayoutManualRefrash.Instance._activeinEndList.Contains(rt))
            {
                LayoutManualRefrash.Instance._activeinEndList.Add(rt);
            }
            if (!updateParent && !LayoutManualRefrash.Instance._notUpdateParentList.Contains(rt))
            {
                LayoutManualRefrash.Instance._notUpdateParentList.Add(rt);
            }
        }
        public static void ForceUpdateLayoutFromLowest(Transform rt)
        {
            if (rt == null)
                return;
            bool result = false;
            for (int i = 0; i < rt.childCount; i++)
            {
                LayoutElement le = rt.GetChild(i).GetComponent<LayoutElement>();
                AspectRatioFitter arf = rt.GetChild(i).GetComponent<AspectRatioFitter>();
                ContentSizeFitter csf = rt.GetChild(i).GetComponent<ContentSizeFitter>();
                GridLayoutGroup glg = rt.GetChild(i).GetComponent<GridLayoutGroup>();
                VerticalLayoutGroup vlg = rt.GetChild(i).GetComponent<VerticalLayoutGroup>();
                HorizontalLayoutGroup hlg = rt.GetChild(i).GetComponent<HorizontalLayoutGroup>();

                if (le != null || arf != null || csf != null || glg != null || vlg != null || hlg != null)
                {
                    result = true;
                    ForceUpdateLayoutFromLowest(rt.GetChild(i));
                }
            }

            if (!result)
            {
                Instance.SetDirty(rt);
            }
        }


    }
// }
